#include "diskanalysis.h"
#include <QFileInfo>
#include <QDir>
#include <iostream>
#include <string.h>
#include <math.h>
#include <QDebug>
CDirInfo::CDirInfo(QObject *parent):QObject(parent),
_size(0),_dir_cnt(0),_file_cnt(0),_file_size(0),
_dircnt_t(0), _filecnt_t(0),_parent(nullptr),_depth(0)
{
}

CDirInfo::~CDirInfo()
{
}

int CDirInfo::Analysis_impl(QString path, int depth)
{
	_path = path; _depth = depth++;
	//std::cout << qPrintable(_path) << std::endl;
    _vtFiles.clear();

	QDir dir(path);
	if (!dir.exists())
		qWarning("Cannot find the example directory");

	dir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::NoSymLinks);
	//dir.setSorting(QDir::Size | QDir::Reversed);
	_dirName = dir.dirName();
    float progress = 0.0f;
	QFileInfoList list = dir.entryInfoList();
	//std::cout << "     Bytes Filename" << std::endl;
	int fsize = list.size();
	for (int i = 0; i < list.size(); ++i) {

		QFileInfo fileInfo = list.at(i);

		if (fileInfo.fileName() == "." || fileInfo.fileName() == "..")
			continue;

		if (fileInfo.isDir())
		{
//            if(_depth<2)
//            qDebug() << "PATH(" << _depth<<"):" << qPrintable(QString("%1 %2").arg(0, 10)
//                .arg(fileInfo.fileName()));

			_dir_cnt++;
			CDirInfo *pDir = new CDirInfo();
			pDir->_parent = this;
			_vtDirPtr.append(pDir);
			pDir->Analysis_impl(fileInfo.absoluteFilePath(), depth);
			on_add_dir();
		}
		else
		{
			qlonglong  filesize = fileInfo.size();
            //qDebug() << "FILE(" << _depth << "):" << qPrintable(QString("%1 %2").arg(filesize, 10)
             //   .arg(fileInfo.fileName()));
            fileinfo fi;
            fi.name = fileInfo.fileName();
            fi.size = filesize;
            _vtFiles.append(fi);

			_file_size += filesize;
			_file_cnt++;
			on_add_file(filesize);
		}

        _progress = float(i+1)/fsize;
        this->updateProg();

        if(this->_parent &&  depth ==1 )
        {
            _parent->updateProg(_progress*pow(0.1,depth+1));
        }
    }
	return 0;
}

void CDirInfo::sort()
{
	CDirInfo *tmpPtr = nullptr;

	for (int i = 0; i < _vtDirPtr.size(); i++)
	{
		for (int j = i; j <  _vtDirPtr.size(); j++)
		{
			if (_vtDirPtr[i]->_size < _vtDirPtr[j]->_size)
			{
				tmpPtr = _vtDirPtr[i];
                _vtDirPtr[i] = _vtDirPtr[j];
				_vtDirPtr[j] = tmpPtr;
			}
		}
    }
}

void CDirInfo::updateProg(float p)
{
    emit progress(_progress+p);
}

int CDirInfo::Analysis(QString path)
{
	int depth = 0;
	Analysis_impl(path, depth);
	
//	this->sort();

//	qulonglong size = 0;
//	for (int j = 0; j < _vtDirPtr.size(); j++)
//	{
//		size += _vtDirPtr[j]->_size;
//		if (_vtDirPtr[j]->_dircnt_t>0)
//		{
//			std::cout << qPrintable(_vtDirPtr[j]->_path) << std::endl;
//		}
//	}
//	size += this->_file_size;

	emit finished();

	return 0;
}


void CDirInfo::on_add_file(qulonglong filesize)
{
	_size += filesize;
	_filecnt_t++;
	if (_parent)
		_parent->on_add_file(filesize);
}

void CDirInfo::on_add_dir()
{
	_dircnt_t++;
	if (_parent)
		_parent->on_add_dir();
}
